home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / groff108.lha / groff-1.08 / libgroff / string.cc < prev    next >
C/C++ Source or Header  |  1992-08-03  |  6KB  |  311 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.com)
  4.  
  5. This file is part of groff.
  6.  
  7. groff is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 2, or (at your option) any later
  10. version.
  11.  
  12. groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License along
  18. with groff; see the file COPYING.  If not, write to the Free Software
  19. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include <stdio.h>
  22. #include "stringclass.h"
  23. #include "lib.h"
  24.  
  25. static char *salloc(int len, int *sizep);
  26. static void sfree(char *ptr, int size);
  27. static char *sfree_alloc(char *ptr, int size, int len, int *sizep);
  28. static char *srealloc(char *ptr, int size, int oldlen, int newlen, int *sizep);
  29.  
  30. static char *salloc(int len, int *sizep)
  31. {
  32.   if (len == 0) {
  33.     *sizep = 0;
  34.     return 0;
  35.   }
  36.   else
  37.     return new char[*sizep = len*2];
  38. }
  39.  
  40. static void sfree(char *ptr, int)
  41. {
  42.   a_delete ptr;
  43. }
  44.  
  45. static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
  46. {
  47.   if (oldsz >= len) {
  48.     *sizep = oldsz;
  49.     return ptr;
  50.   }
  51.   a_delete ptr;
  52.   if (len == 0) {
  53.     *sizep = 0;
  54.     return 0;
  55.   }
  56.   else
  57.     return new char[*sizep = len*2];
  58. }
  59.  
  60. static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen, int *sizep)
  61. {
  62.   if (oldsz >= newlen) {
  63.     *sizep = oldsz;
  64.     return ptr;
  65.   }
  66.   if (newlen == 0) {
  67.     a_delete ptr;
  68.     *sizep = 0;
  69.     return 0;
  70.   }
  71.   else {
  72.     char *p = new char[*sizep = newlen*2];
  73.     if (oldlen < newlen && oldlen != 0)
  74.       memcpy(p, ptr, oldlen);
  75.     a_delete ptr;
  76.     return p;
  77.   }
  78. }
  79.  
  80. string::string() : len(0), ptr(0), sz(0)
  81. {
  82. }
  83.  
  84. string::string(const char *p, int n) : len(n)
  85. {
  86.   assert(n >= 0);
  87.   ptr = salloc(n, &sz);
  88.   if (n != 0)
  89.     memcpy(ptr, p, n);
  90. }
  91.  
  92. string::string(const char *p)
  93. {
  94.   if (p == 0) {
  95.     len = 0;
  96.     ptr = 0;
  97.     sz = 0;
  98.   }
  99.   else {
  100.     len = strlen(p);
  101.     ptr = salloc(len, &sz);
  102.     memcpy(ptr, p, len);
  103.   }
  104. }
  105.  
  106. string::string(char c) : len(1)
  107. {
  108.   ptr = salloc(1, &sz);
  109.   *ptr = c;
  110. }
  111.  
  112. string::string(const string &s) : len(s.len)
  113. {
  114.   ptr = salloc(len, &sz);
  115.   if (len != 0)
  116.     memcpy(ptr, s.ptr, len);
  117. }
  118.   
  119. string::~string()
  120. {
  121.   sfree(ptr, sz);
  122. }
  123.  
  124. string &string::operator=(const string &s)
  125. {
  126.   ptr = sfree_alloc(ptr, sz, s.len, &sz);
  127.   len = s.len;
  128.   if (len != 0)
  129.     memcpy(ptr, s.ptr, len);
  130.   return *this;
  131. }
  132.  
  133. string &string::operator=(const char *p)
  134. {
  135.   if (p == 0) {
  136.     sfree(ptr, len);
  137.     len = 0;
  138.     ptr = 0;
  139.     sz = 0;
  140.   }
  141.   else {
  142.     int slen = strlen(p);
  143.     ptr = sfree_alloc(ptr, sz, slen, &sz);
  144.     len = slen;
  145.     memcpy(ptr, p, len);
  146.   }
  147.   return *this;
  148. }
  149.  
  150. string &string::operator=(char c)
  151. {
  152.   ptr = sfree_alloc(ptr, sz, 1, &sz);
  153.   len = 1;
  154.   *ptr = c;
  155.   return *this;
  156. }
  157.  
  158. void string::move(string &s)
  159. {
  160.   sfree(ptr, sz);
  161.   ptr = s.ptr;
  162.   len = s.len;
  163.   sz = s.sz;
  164.   s.ptr = 0;
  165.   s.len = 0;
  166.   s.sz = 0;
  167. }
  168.  
  169. void string::grow1()
  170. {
  171.   ptr = srealloc(ptr, sz, len, len + 1, &sz);
  172. }
  173.  
  174. string &string::operator+=(const char *p)
  175. {
  176.   if (p != 0) {
  177.     int n = strlen(p);
  178.     int newlen = len + n;
  179.     if (newlen > sz)
  180.       ptr = srealloc(ptr, sz, len, newlen, &sz);
  181.     memcpy(ptr + len, p, n);
  182.     len = newlen;
  183.   }
  184.   return *this;
  185. }
  186.  
  187. string &string::operator+=(const string &s)
  188. {
  189.   if (s.len != 0) {
  190.     int newlen = len + s.len;
  191.     if (newlen > sz)
  192.       ptr = srealloc(ptr, sz, len, newlen, &sz);
  193.     memcpy(ptr + len, s.ptr, s.len);
  194.     len = newlen;
  195.   }
  196.   return *this;
  197. }
  198.  
  199. void string::append(const char *p, int n)
  200. {
  201.   if (n > 0) {
  202.     int newlen = len + n;
  203.     if (newlen > sz)
  204.       ptr = srealloc(ptr, sz, len, newlen, &sz);
  205.     memcpy(ptr + len, p, n);
  206.     len = newlen;
  207.   }
  208. }
  209.  
  210. string::string(const char *s1, int n1, const char *s2, int n2)
  211. {
  212.   assert(n1 >= 0 && n2 >= 0);
  213.   len = n1 + n2;
  214.   if (len == 0) {
  215.     sz = 0;
  216.     ptr = 0;
  217.   }
  218.   else {
  219.     ptr = salloc(len, &sz);
  220.     if (n1 == 0)
  221.       memcpy(ptr, s2, n2);
  222.     else {
  223.       memcpy(ptr, s1, n1);
  224.       if (n2 != 0)
  225.     memcpy(ptr + n1, s2, n2);
  226.     }
  227.   }
  228. }
  229.  
  230. int operator<=(const string &s1, const string &s2)
  231. {
  232.   return (s1.len <= s2.len
  233.       ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
  234.       : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
  235. }
  236.  
  237. int operator<(const string &s1, const string &s2)
  238. {
  239.   return (s1.len < s2.len
  240.       ? s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) <= 0
  241.       : s2.len != 0 && memcmp(s1.ptr, s2.ptr, s2.len) < 0);
  242. }
  243.  
  244. int operator>=(const string &s1, const string &s2)
  245. {
  246.   return (s1.len >= s2.len
  247.       ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
  248.       : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
  249. }
  250.  
  251. int operator>(const string &s1, const string &s2)
  252. {
  253.   return (s1.len > s2.len
  254.       ? s2.len == 0 || memcmp(s1.ptr, s2.ptr, s2.len) >= 0
  255.       : s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) > 0);
  256. }
  257.  
  258. void string::set_length(int i)
  259. {
  260.   assert(i >= 0);
  261.   if (i > sz)
  262.     ptr = srealloc(ptr, sz, len, i, &sz);
  263.   len = i;
  264. }
  265.  
  266. void string::clear()
  267. {
  268.   len = 0;
  269. }
  270.  
  271. int string::search(char c) const
  272. {
  273.   char *p = (char *)memchr(ptr, c, len);
  274.   return p ? p - ptr : -1;
  275. }
  276.  
  277. // we silently strip nuls
  278.  
  279. char *string::extract() const
  280. {
  281.   char *p = ptr;
  282.   int n = len;
  283.   int nnuls = 0;
  284.   for (int i = 0; i < n; i++)
  285.     if (p[i] == '\0')
  286.       nnuls++;
  287.   char *q = new char[n + 1 - nnuls];
  288.   char *r = q;
  289.   for (i = 0; i < n; i++)
  290.     if (p[i] != '\0')
  291.       *r++ = p[i];
  292.   q[n] = '\0';
  293.   return q;
  294. }
  295.  
  296. void put_string(const string &s, FILE *fp)
  297. {
  298.   int len = s.length();
  299.   const char *ptr = s.contents();
  300.   for (int i = 0; i < len; i++)
  301.     putc(ptr[i], fp);
  302. }
  303.  
  304. string as_string(int i)
  305. {
  306.   static char buf[INT_DIGITS + 2];
  307.   sprintf(buf, "%d", i);
  308.   return string(buf);
  309. }
  310.  
  311.